Due to advancements in processing technology, complex integrated circuits (ICs) can be designed at various levels of abstraction. Using a hardware description language (HDL), circuits can be designed at the gate level, the register transfer level (RTL), and higher logical levels. When designing using an HDL, the design is often structured in a modular manner. The designer describes a module in terms of the behavior of a system, the behavior describing the generation and propagation of signals through modules of combinatorial logic from one set of registers to another set of registers. HDLs provide a rich set of constructs to describe the functionality of a module. Modules may be combined and augmented to form even higher-level modules.
Prior to implementation, an HDL-based design can be simulated to determine whether the design will function as required. Wasted manufacturing costs due to faulty design may thereby be avoided. Numerous tools are available for simulating circuit designs including, for example, high-level modeling systems (HLMS) and HDL simulators.
Simulation of an HDL-based design comprises a compilation phase and a runtime simulation phase. In the compilation phase, HDL source code is input, analyzed, and elaborated to generate executable simulation code. In the runtime simulation phase, the code generated in the compilation phase is executed by a simulation engine to simulate the design.
From a user perspective, HDL simulators work by compiling the HDL-based design once, and then executing the compiled design many times during the runtime phase. Therefore, the runtime performance of HDL simulators is of critical importance, and may be more important than compile time performance.
An HDL-based design is a hierarchy of modules, whose behavior is described by means of HDL processes. When the HDL-based design is written in the VHDL language, an HDL process corresponds to either a VHDL process, a concurrent signal assignment, or a concurrent assertion. When the HDL-based design is written in the Verilog language, an HDL process corresponds to either a Verilog always block, an initial block, an assign statement, or a gate. Procedure calls may or may not be regarded as HDL processes. From a hardware perspective, the HDL processes represent hardware that responds to changes in inputs. For example, a change to an output of one circuit may trigger responses in multiple circuits having inputs coupled to the output.
HDL simulators schedule execution of HDL statements such that global variables or signals input to the HDL statements are properly updated and race conditions between concurrent HDL statements are avoided. Simulation of HDL processes is performed over a number of simulation cycles. Each simulation cycle begins with updates to values of nets. Each net, which may be a VHDL signal or a Verilog net, represents values transmitted in a wire of a circuit design. For ease of reference, VHDL signals and Verilog nets may be referred to as either signals or nets, and such terms are used interchangably herein. Each update to a net may trigger a number of processes which model how a hardware implementation of the design would respond. Processes dependent on the updated nets are scheduled and executed in a delta cycle.
Depending on the circuit design, a net may be changed or updated by the output of multiple processes. Each process output that may affect a net is referred to as a driver. If a process has several statements assigning values to the same net, only one driver for the net is created per process. The value of the driver is computed from all the values assigned to that signals in the process, according to predefined language rules. A net that has at most one driver for each bit is said to be singly-driven. A net that has several drivers on the same set of bits is said to be multiply-driven.
When a net is driven by multiple drivers, a value of the net is determined when nets are updated at runtime using a resolution function. The value computed by the resolution function is referred to as the resolved value, and the resolved value will be assigned as the new value of the net. The process of computing the new value from the driver values of a net is called driver resolution. The resolution function can be standard, defined by the HDL language itself or, for VHDL, can be user defined.
Previous methods for simulation of HDL circuit designs compile the designs and generate simulation code on a module-by-module basis, with no regard to inter-module signal dependencies. Rather, dependancies between drivers, nets, and processes are determined dynamically at runtime. As a result, it is not determined whether a net is multiply-driven or singly-driven until runtime. Accordingly, the simulation code generated by the previous methods at compile time must be general enough to be capable of handling either singly-driven or multiply-driven nets. Large data structures of pointers are created to store the values of drivers and nets, as well as determined dependencies between the two. These data structures require a significant amount of memory to store data values and pointers between the data structures.
The data structures are either general enough to handle multiply-driven scenarios even for the singly-driven nets, or are dynamically created at runtime. Because multiply-driven nets require more complex data structures, the general data structures are computationally inefficient for singly-driven nets. Furthermore, when data structures are dynamically created, memory to store the values of drivers and signals is allocated at runtime. Due to the dynamic allocation of memory, driver values that are needed to resolve the value of a net at runtime may be stored in separate locations of memory. As a result, the resolution function may have to separately access a large number of different locations of memory to retrieve all the driver values that are needed to resolve the value of a net. Due to the large number of nets and drivers used in a typical simulation of an HDL circuit design, these separate memory accesses by the resolution function can significantly impact simulation runtime.
One or more embodiments may address one or more of the above issues.